package server.xmpp;

/**
 * This package contains embedded XMPP server class  

 * @author Maris
 *
 */
import java.beans.XMLEncoder;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.vysper.mina.TCPEndpoint;
import org.apache.vysper.storage.StorageProviderRegistry;
import org.apache.vysper.xml.fragment.XMLElementBuilder;
import org.apache.vysper.xmpp.addressing.Entity;
import org.apache.vysper.xmpp.addressing.EntityFormatException;
import org.apache.vysper.xmpp.addressing.EntityImpl;
import org.apache.vysper.xmpp.delivery.failure.DeliveryException;
import org.apache.vysper.xmpp.delivery.failure.IgnoreFailureStrategy;
import org.apache.vysper.xmpp.modules.extension.xep0092_software_version.SoftwareVersionModule;
import org.apache.vysper.xmpp.server.*;
import org.apache.vysper.xmpp.stanza.IQStanzaType;
import org.apache.vysper.xmpp.stanza.MessageStanzaType;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;

import server.xmpp.pingmodule.MyXMPPPingModule;

public class XMPPServerClass {

	private String servername;
	private int port = 5222;
	private String authKeyFile;
	private String authPasswd;
	private XMPPServer server;
	private static XMPPServerClass xmppserverclassobject;

	/**
	 * Implementation of the singleton pattern using lazy instantiation. See
	 * XMPPClient.java for more details
	 */
	private XMPPServerClass(HashMap<String, String> config) {
		this.servername = config.get("domain");
		this.port = Integer.parseInt(config.get("xmpp_server_port"));
		this.authKeyFile = config.get("auth_key_file");
		this.authPasswd = config.get("authPass");
	}

	private XMPPServerClass() {
	}
	
	public static synchronized XMPPServerClass getInstance(
			HashMap<String, String> config) {
		if (xmppserverclassobject == null) {
			xmppserverclassobject = new XMPPServerClass(config);
		}
		return xmppserverclassobject;
	}

	public static synchronized XMPPServerClass getInstance() {
		if (xmppserverclassobject == null) {
			xmppserverclassobject = new XMPPServerClass();
		}
		return xmppserverclassobject;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}

	public void init(StorageProviderRegistry providerRegistry)
			throws FileNotFoundException {

		server = new XMPPServer(servername);
		server.addEndpoint(new TCPEndpoint());
		server.setStorageProviderRegistry(providerRegistry);
		server.setTLSCertificateInfo(new File(authKeyFile), authPasswd);

		try {
			server.start();
			System.out.println("Started.");
		} catch (Exception e) {
			e.printStackTrace();
		}
		server.addModule(new SoftwareVersionModule());
		server.addModule(new MyXMPPPingModule());

	}
/**
 * 	
 * status indicates locked if 1
 * @author User
 * @param	<String filename, String[] {username, status}>
 */ 
	public void sendNewFileList( HashMap<String,String[]> hm) { 
    	String file="", username = null, body = null;
    	final String LANG = "en";
    	Stanza stanza = null;
    	Iterator<String> it = hm.keySet().iterator();
    	while (it.hasNext()) {
            file = it.next();
            String [] fileinfo = hm.get(file);
            System.out.println("Filename: " + file+ " Values: "+ fileinfo[0] + " and "+fileinfo[1]);
        }
    	try {
			StanzaBuilder sb = StanzaBuilder.createMessageStanza(
					EntityImpl.parse(servername), 
					EntityImpl.parse(username),
					MessageStanzaType.HEADLINE, 
					LANG, 
					body);
		} catch (EntityFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//    	Entity to = null;
//    	try {
//			server.getServerRuntimeContext().getStanzaRelay().relay(to, stanza, new IgnoreFailureStrategy());
//		} catch (DeliveryException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
	public void sendSomething( Entity to ) throws FileNotFoundException { 
    	Entity from = null;
       	final String LANG = "en";
       	String body = "Bubis baisais";
       	
       	try {			
			from = EntityImpl.parse(servername); 
		} catch (EntityFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       	
//       	ByteArrayOutputStream os1 = new ByteArrayOutputStream();
//       	ByteArrayOutputStream os2 = new ByteArrayOutputStream();
//       	FileOutputStream f_out = new 
//       			FileOutputStream("myobject.data");
//       	
//       	XMLEncoder encoder1 = new XMLEncoder(f_out);
//       	encoder1.writeObject(body);
//       	
//       	String stream = null;
//       	try {
//	       	ObjectOutputStream encoder2 = new ObjectOutputStream(os2);
//			encoder2.writeObject(body);
//			encoder2.close();
//	        stream = encoder2.toString();
//       	} catch (IOException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
       	
		Stanza stanza = StanzaBuilder.createMessageStanza(
				from, to, MessageStanzaType.HEADLINE, LANG, body).build();
    	try {

			server.getServerRuntimeContext().getStanzaRelay().relay(to, stanza, new IgnoreFailureStrategy());
		} catch (DeliveryException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void destroy() {
		server.stop();
	}
}
